/*
 * Dispatcher.java    0.0.1    17/set/2009
 * 
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */ 
package org.mentalsmash.tazio.net.cs.server.impl;

import java.io.IOException;
import java.nio.channels.SelectableChannel;

import org.mentalsmash.tazio.net.cs.server.ProtocolHandler;

/**
 * The Dispatcher has the role to listen for client connections over the
 * listening socket, and to dispatch connection to appropriate handler threads.
 * The idea (that a dispatcher should implement) is to use nonblocking IO along with
 * readiness selection, to allow a small pool of threads to manage a great number of
 * connections.
 * <p>
 * This class and all the classes in this package are largely inspired to the presentation
 * "How To Build A Scalable NIO Server, Mark II" by Ron Hitchens (http://ronsoft.com)
 * </p>
 * @version    0.0.1    17/set/2009     
 * @author     Andrea Reale <andrea.reale@gmail.com>
 */
/*
 * TODO: There's something wrong in this interface: there's no start() method but everybody
 *       seems to need the dispatcher's start method to make it run, while nobody needs to explicitely
 *       call the dispatch() method (that is automatically called by start() ).
 *       Maybe it won't be a bad idea to substitute the dispatch() method in the interface with the 
 *       start method, so that classes like the concrete Acceptors or CSComFacade will no longer
 *       depend on a concrete Dispatcher implementation.
 */       
public  interface Dispatcher {
	/**
	 * Starts the dispatch cycle. During this cycle the dispatcher checks for readiness
	 * the channels that are registered on it, and if it is the case runs the associated handler
	 * @return the Thread that is running the dispatcher
	 * @throws IOException If any dispatching problem happens
	 */
	Thread start();
	
	/**
	 * Stop this dispatcher's dispatching cycle. After calling this method the dispacher will
	 * stop dispatching clients' connections, and its associated channels will be unregeisterd
	 */
	void stop();
	
	/**
	 * Register a selectable channel for the dispacther to watch. On readiness event
	 * the handler's nextMessage() will be called.
	 * @param chan the selectable channel to read from
	 * @param handler the application handler to handle incoming messages
	 * @throws IOException If some problem occurs during the registration process
	 * @return a reference to the facade of the registered channel
	 */
	ChannelFacade register(SelectableChannel chan, ProtocolHandler handler)
	    throws IOException;
	
	
	/**
	 * Unregister the selectable channel from readiness events notifications
	 * @param chan the selectable channel to unregister
	 */
	void unregister(ChannelFacade chan);
	
	/**
	 * Used to test whether the dispather is dispatching
	 * @return true if the dispatcher is in the dispatching cycle
	 */
	boolean isDispatching();
	
	/**
	 * Get the number of channels that the dispatcher is working on.
	 * @return the number of channels that the dispatcher is working on.
	 */
	int getNumSources();
	
	/**
	 * The number of requests currently handled by working threads
	 * that were launched by this dispatcher
	 * @return the number of requests currently handled by working threads
	 *         that were launched by this dispatcher
	 */
	int getNumRequestsServed();
	
	/**
	 * Register a lister on the dispatcher. Appropriate methods of registered listeners will be
	 * invoked upon interesting events occurrences.
	 * @param listener an instance of <tt>DispatcherListener</tt>
	 * @return true if the registration is successful 
	 */
	boolean registerListener(DispatcherListener listener);
	/**
	 * Removes a listener from the listeners which are registered on the dispatcher. If the
	 * listener was not previously registered on the dispatcher nothing is done.
	 * @param listener a reference to the listener to remove
	 * @return true if the listener was found and removed, false if the listener was not registered.
	 */
	boolean removeListener(DispatcherListener listener);
	

	
}
